package com.kaithan.monitor.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;

/**
 * 类描述：安全配置
 *
 * @author ZhuYin
 * @since 2025年03月09日
 */
@Configuration
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
                // 权限控制配置
                .authorizeHttpRequests(auth -> auth.requestMatchers("/actuator/**").permitAll().requestMatchers("/assets/**").permitAll().requestMatchers("/login").permitAll().requestMatchers("/logout").permitAll()
                        // 允许客户端注册接口的 POST 请求（需 Basic 认证）
                        .requestMatchers(HttpMethod.POST, "/instances").authenticated().anyRequest().authenticated())
                // 表单登录配置
                .formLogin(form -> form.loginPage("/login").defaultSuccessUrl("/", true))
                // 启用 HTTP Basic 认证（用于客户端注册）
                .httpBasic(Customizer.withDefaults())
                // 安全退出配置
                .logout(logout -> logout.logoutUrl("/logout").permitAll())
                // CSRF 配置（保留对客户端注册端点的保护） 允许 Admin 客户端注册
                .csrf(csrf -> csrf.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()).ignoringRequestMatchers("/instances", "/actuator/**", "/login", "/logout"));

        return http.build();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return PasswordEncoderFactories.createDelegatingPasswordEncoder();
    }

    public static void main(String[] args) {
        PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
        String encode = encoder.encode("tlkj@admin123!");
        System.out.println(encode);
    }
}